package com.app.business.calculate;

import com.app.business.model.*;
import com.app.business.service.*;
import com.app.system.utils.ApplicationContextProvider;
import com.app.system.utils.CollectionUtils;
import com.app.system.utils.dataType.BigDecimalUtils;
import com.app.system.utils.dataType.StringUtils;
import com.google.common.collect.Maps;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * 计算缴款金额
 * Created by ZYK on 2019/6/10.
 */
@SuppressWarnings("all")
public class CalculateHandInMoneyUtils {
    private static ContractService contractService;
    private static HouseService houseService;
    private static CarLotService carLotService;
    private static HandInMoneyService handInMoneyService;
    private static BuyHousePersonService buyHousePersonService;

    /**
     * @param contractId
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public synchronized static void main(Integer contractId) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
        contractService = (ContractService) applicationContext.getBean(ContractService.class);
        handInMoneyService = (HandInMoneyService) applicationContext.getBean(HandInMoneyService.class);
        Contract contract = contractService.findOne(contractId);
        if (contract == null) {
            return;
        }
        CalculateUtils.main(contract.getId());
        contract = calHandInMoney(contract);
        contract = calShouldHandInMoney(contract);
        calQiHouseMoney(contract);
        System.out.println("已缴款金额计算完成！");
        System.out.println("已缴款金额计算完成！");
        contractService.save(contract);
    }

    /**
     * 计算已缴款金额
     *
     * @param contract
     * @return
     */
    private static Contract calHandInMoney(Contract contract) {
        BigDecimal handInMoneyAll = BigDecimal.ZERO;
        List<HandInMoney> handInMoneyList = handInMoneyService.getHandInMoneyListByContractId(contract.getId());
        if (CollectionUtils.isNotEmpty(handInMoneyList)) {
            for (HandInMoney handInMoney : handInMoneyList) {
                handInMoneyAll = BigDecimalUtils.getSum(handInMoneyAll, handInMoney.getHandInMoney());
            }
        }
        contract.setHandInMoney(handInMoneyAll);
        return contract;
    }

    /**
     * i计算应缴款金额
     */
    private static Contract calShouldHandInMoney(Contract contract) {
        BigDecimal shouldHandInMoney = BigDecimal.ZERO;
        if (contract.getFinalMoney().compareTo(new BigDecimal("0")) < 0) {
            shouldHandInMoney = contract.getFinalMoney();
        }
        contract.setShouldHandInMoney(shouldHandInMoney);
        return contract;
    }

    /**
     * 计算期房部分缴款金额
     */
    public static Map calQiHouseMoney(Contract contract) {
        ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
        houseService = (HouseService) applicationContext.getBean(HouseService.class);
        carLotService = (CarLotService) applicationContext.getBean(CarLotService.class);
        Map map = Maps.newHashMap();
        String cwQiHouseMemo = "";
        String cwQiCarLotMemo = "";
        //获取已选期房房源
        List<House> houseNature2List = houseService.getHouseListByContractIdAndHouseNature2(contract.getId());
        //获取已选现房房源
        List<House> houseNature1List = houseService.getHouseListByContractIdAndHouseNature1(contract.getId());
        BigDecimal xianFangResultMoney = null;
        BigDecimal qiFangResultMoney = null;
        if (CollectionUtils.isNotEmpty(houseNature2List)) {

            cwQiHouseMemo = "其中选择现房" + houseNature1List.size() + "套，面积:" + contract.getChooseHouseXianFangAreaTotal() + "㎡；";
            cwQiHouseMemo = cwQiHouseMemo + "其中选择期房" + houseNature2List.size() + "套，面积:" + contract.getChooseHouseQiFangAreaTotal() + "㎡；";

            if (contract.getResultMoney().compareTo(BigDecimal.ZERO) < 0) {
                //已选现房部分占总选房面积比例
                BigDecimal bl = BigDecimalUtils.getBigAndBigDiv(contract.getChooseHouseXianFangAreaTotal(), contract.getChooseHouseAreaTotal(), 10);
                if (bl.compareTo(BigDecimal.ONE) >= 0) {
                    bl = BigDecimal.ONE;
                }
                xianFangResultMoney = BigDecimalUtils.getBigAndBigMul(contract.getResultMoney(), bl).setScale(2, BigDecimal.ROUND_HALF_UP);
                qiFangResultMoney = BigDecimalUtils.getBigAndBigSub(contract.getResultMoney(), xianFangResultMoney);
                map.put("xianFangResultMoney", xianFangResultMoney);
                map.put("qiFangResultMoney", qiFangResultMoney);

                cwQiHouseMemo = cwQiHouseMemo + "现房部分应缴交对抵后金额:" + xianFangResultMoney + "元；";
                cwQiHouseMemo = cwQiHouseMemo + "期房部分应缴交对抵后金额:" + qiFangResultMoney + "元；";

            }
            if (contract.getHouseMoney().compareTo(BigDecimal.ZERO) < 0) {
                cwQiHouseMemo = cwQiHouseMemo + "扩购部分应补金额:" + contract.getHouseMoney() + "元；";
            }
            cwQiHouseMemo = cwQiHouseMemo + "期房部分公维金:" + BigDecimalUtils.getBigAndBigMul(contract.getChooseHouseQiFangAreaTotal(), contract.getParameter().getZzbcwxPrice()).setScale(2, BigDecimal.ROUND_HALF_UP).negate() + "元。";
            map.put("cwQiHouseMemo", cwQiHouseMemo);
        }

        //获取已选期房车位
        List<CarLot> carLotNatureList = carLotService.getCarLotListByContractIdAndHouseNature(contract.getId(), 2);

        BigDecimal carLotNatureArea = BigDecimal.ZERO;
        BigDecimal carLotNaturePrice = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(carLotNatureList)) {
            for (CarLot carLot : carLotNatureList) {
                carLotNatureArea = BigDecimalUtils.getSum(carLotNatureArea, carLot.getBuildArea());
                carLotNaturePrice = BigDecimalUtils.getSum(carLotNaturePrice, carLot.getPrice());
            }
            cwQiCarLotMemo = "其中选择期房车位" + carLotNatureList.size() + "个,面积:" + carLotNatureArea + "㎡,期房车位总价:" + carLotNaturePrice + "元,期房车位部分公维金:" +
                    BigDecimalUtils.getBigAndBigMul(carLotNatureArea, contract.getParameter().getCwbcwxPrice()).setScale(2, BigDecimal.ROUND_HALF_UP).negate() + "元。";
        }
        map.put("cwQiCarLotMemo", cwQiCarLotMemo);
        return map;
    }


    /**
     * i计算已选部分缴款金额
     */
    public static Map calPartTakeHouseMoney(Contract contract, List<House> houseList, List<CarLot> carLotList) {
        ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
        houseService = (HouseService) applicationContext.getBean(HouseService.class);
        carLotService = (CarLotService) applicationContext.getBean(CarLotService.class);
        buyHousePersonService = (BuyHousePersonService) applicationContext.getBean(BuyHousePersonService.class);
        Map map = Maps.newHashMap();

        //本次所选择房源面积
        BigDecimal nowHandMoneyHouseArea = BigDecimal.ZERO;
        //剩余所选择房源面积
        BigDecimal syHandMoneyHouseArea = BigDecimal.ZERO;
        //本次所选择房源应缴交对抵后金额
        BigDecimal nowHandMoneyResultMoney = BigDecimal.ZERO;
        //剩余其他所选择房源应缴交对抵后金额
        BigDecimal syHandMoneyResultMoney = BigDecimal.ZERO;

        String nameStr = "";
        List<String> nameList = new ArrayList<>();
        String idCardStr = "";
        List<String> idCardList = new ArrayList<>();
        String houseNumStrList = "";
        List<BuyHousePerson> buyHousePersonList = new ArrayList<>();
        //循环当前所选择房源面积
        if (CollectionUtils.isNotEmpty(houseList)) {
            for (House house : houseList) {
                nowHandMoneyHouseArea = BigDecimalUtils.getSum(nowHandMoneyHouseArea, house.getBuildArea());
                houseNumStrList = houseNumStrList + house.getAzProject().getProjectName() + house.getHouseNumStr() + "、";
                buyHousePersonList = buyHousePersonService.getBuyHousePersonListByHouseId(house.getId());

                if (CollectionUtils.isNotEmpty(buyHousePersonList)) {
                    for (BuyHousePerson buyHousePerson : buyHousePersonList) {
                        nameList.add(buyHousePerson.getName());
                        idCardList.add(buyHousePerson.getIdCard());
                    }
                }
            }
        }
        //根据当前所选择房源面积，得到当前应缴交比例和剩余对抵后金额
        if (contract.getResultMoney() != null && contract.getResultMoney().compareTo(BigDecimal.ZERO) < 0) {
            //本次选房房源部分占总选房面积比例
            BigDecimal bl = BigDecimalUtils.getBigAndBigDiv(nowHandMoneyHouseArea, contract.getChooseHouseAreaTotal(), 10);
            if (bl.compareTo(BigDecimal.ONE) >= 0) {
                bl = BigDecimal.ONE;
            }
            nowHandMoneyResultMoney = BigDecimalUtils.getBigAndBigMul(contract.getResultMoney(), bl).setScale(2, BigDecimal.ROUND_HALF_UP);
            syHandMoneyResultMoney = BigDecimalUtils.getBigAndBigSub(contract.getResultMoney(), nowHandMoneyResultMoney);
        }
        syHandMoneyHouseArea = BigDecimalUtils.getBigAndBigSub(contract.getChooseHouseAreaTotal(), nowHandMoneyHouseArea);
        //本次所选择房源面积
        map.put("nowHandMoneyHouseArea", nowHandMoneyHouseArea);
        //剩余所选择房源面积
        map.put("syHandMoneyHouseArea", syHandMoneyHouseArea);
        //本次已交对抵后金额
        map.put("nowHandMoneyResultMoney", BigDecimalUtils.getAbsolute(nowHandMoneyResultMoney));
        //剩余应缴交对抵后金额
        map.put("syHandMoneyResultMoney", BigDecimalUtils.getAbsolute(syHandMoneyResultMoney));


        //本次所选择房源扩购金额
        BigDecimal nowKgMoney = BigDecimal.ZERO;
        //剩余所选择房源扩购金额
        BigDecimal syKgMoney = BigDecimal.ZERO;

        if (contract.getHouseMoney().compareTo(BigDecimal.ZERO) < 0) {
            nowKgMoney = BigDecimalUtils.getAbsolute(contract.getHouseMoney());
            if (syHandMoneyHouseArea.compareTo(BigDecimal.ZERO) > 0) {
                nowKgMoney = BigDecimal.ZERO;
                syKgMoney = BigDecimalUtils.getAbsolute(contract.getHouseMoney());
            }
        }
        //本次所选择房源扩购金额
        map.put("nowKgMoney", nowKgMoney);
        //本次所选择房源公维金
        BigDecimal nowXianFangZzGwjMoney = BigDecimalUtils.getBigAndBigMul(nowHandMoneyHouseArea, contract.getParameter().getZzbcwxPrice()).setScale(2, BigDecimal.ROUND_HALF_UP);
        map.put("nowXianFangZzGwjMoney", nowXianFangZzGwjMoney);
        //剩余所选择房源扩购金额
        if (contract.getChooseHouseQiFangAreaTotal().compareTo(BigDecimal.ZERO) > 0) {
            map.put("syQiFangKgMoney", syKgMoney);
        } else {
            map.put("syXianFangKgMoney", syKgMoney);
        }
        //现房剩余公维金
        map.put("syXianFangGwjMoney", BigDecimalUtils.getBigAndBigSub(BigDecimalUtils.getAbsolute(contract.getZzwxXianFangMoney()), nowXianFangZzGwjMoney));
        map.put("syQiFangGwjMoney", BigDecimalUtils.getAbsolute(contract.getZzwxQiFangMoney()));


        //获取本次缴交车位面积，总价，公维金
        BigDecimal nowCarLotArea = BigDecimal.ZERO;
        BigDecimal nowCarLotPrice = BigDecimal.ZERO;
        BigDecimal nowCarLotGwj = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(carLotList)) {
            for (CarLot carLot : carLotList) {
                buyHousePersonList = null;
                nowCarLotArea = BigDecimalUtils.getSum(nowCarLotArea, carLot.getBuildArea());
                nowCarLotPrice = BigDecimalUtils.getSum(nowCarLotPrice, carLot.getPrice());
                houseNumStrList = houseNumStrList + carLot.getAzProject().getProjectName() + carLot.getHouseNumStr() + "、";
                buyHousePersonList = buyHousePersonService.getBuyHousePersonListByCarLotId(carLot.getId());
                if (CollectionUtils.isNotEmpty(buyHousePersonList)) {
                    for (BuyHousePerson buyHousePerson : buyHousePersonList) {
                        nameList.add(buyHousePerson.getName());
                        idCardList.add(buyHousePerson.getIdCard());
                    }
                }
            }
        }
        HashSet<String> nameSet = new HashSet<>(nameList);
        List<String> nameStrList = new ArrayList<>(nameSet);
        HashSet<String> idCardSet = new HashSet<>(idCardList);
        List<String> idCardStrList = new ArrayList<>(idCardSet);

        List<House> houseAllList = houseService.getHouseListByContractId(contract.getId());
        String resultName = StringUtils.getStringByList(nameStrList);
        String resultIdCard = StringUtils.getStringByList(idCardStrList);
        map.put("resultName", resultName.substring(0, resultName.length() - 1));
        map.put("resultIdCard", resultIdCard.substring(0, resultIdCard.length() - 1));
        map.put("houseNumStrList", houseNumStrList.substring(0, houseNumStrList.length() - 1));
        map.put("allHouseNumStrList", houseService.getHouseListStrByContractId(contract.getId()));

        nowCarLotGwj = BigDecimalUtils.getBigAndBigMul(nowCarLotArea, contract.getParameter().getCwbcwxPrice());
        map.put("nowCarLotPrice", nowCarLotPrice);
        map.put("nowCarLotGwj", nowCarLotGwj);
        map.put("syCarLotPrice", BigDecimalUtils.getBigAndBigSub(BigDecimalUtils.getAbsolute(contract.getCarLotMoney()), nowCarLotPrice));
        map.put("syCarLotGwj", BigDecimalUtils.getBigAndBigSub(BigDecimalUtils.getAbsolute(contract.getCwwxMoney()), nowCarLotGwj));
        return map;
    }


    /**
     * 计算住宅公维金部分分别区间缴款金额
     */
    public static Map calGwjMoney(Contract contract) {
        ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
        houseService = (HouseService) applicationContext.getBean(HouseService.class);
        carLotService = (CarLotService) applicationContext.getBean(CarLotService.class);
        Map map = Maps.newHashMap();

        BigDecimal gwjPrice = BigDecimal.ZERO;
        BigDecimal gwjNowPrice = BigDecimal.ZERO;
        BigDecimal gwjArea = BigDecimal.ZERO;
        BigDecimal gwjMoney = BigDecimal.ZERO;
        Map<String, Map<BigDecimal, BigDecimal>> xianFangMap = Maps.newHashMap();
        Map<String, Map<BigDecimal, BigDecimal>> qiFangMap = Maps.newHashMap();
        //获取已选现房房源
        List<House> houseNature1List = houseService.getHouseListByContractIdAndHouseNature1(contract.getId());
        //获取已选期房房源
        List<House> houseNature2List = houseService.getHouseListByContractIdAndHouseNature2(contract.getId());
        if (CollectionUtils.isNotEmpty(houseNature1List)) {
            Map itemMap = Maps.newHashMap();
            for (House house : houseNature1List) {
                gwjPrice = house.getGwjPrice();
                if (gwjPrice.compareTo(BigDecimal.ZERO) > 0) {
                    if (xianFangMap.get(gwjPrice.toString()) == null) {
                        gwjNowPrice = BigDecimalUtils.getBigAndBigMul(house.getGwjPrice(), contract.getParameter().getGwjHouseNowBl());
                        gwjArea = house.getBuildArea();
                        gwjMoney = BigDecimalUtils.getBigAndBigMul(gwjNowPrice, gwjArea).setScale(2, BigDecimal.ROUND_HALF_UP).negate();
                    } else {
                        itemMap = xianFangMap.get(gwjPrice.toString());
                        gwjNowPrice = BigDecimalUtils.getBigAndBigMul(house.getGwjPrice(), contract.getParameter().getGwjHouseNowBl());
                        if (itemMap != null && itemMap.get("gwjArea") != null) {
                            gwjArea = BigDecimalUtils.getSum(house.getBuildArea(), BigDecimalUtils.stringToBigDecimal(itemMap.get("gwjArea").toString()));
                        }
                        gwjMoney = BigDecimalUtils.getBigAndBigMul(gwjNowPrice, gwjArea).setScale(2, BigDecimal.ROUND_HALF_UP).negate();
                    }
                }
                itemMap = Maps.newHashMap();
                itemMap.put("gwjPrice", gwjPrice);
                itemMap.put("gwjNowPrice", gwjNowPrice);
                itemMap.put("gwjArea", gwjArea);
                itemMap.put("gwjMoney", gwjMoney);
                xianFangMap.put(gwjPrice.toString(), itemMap);
            }
        }

        map.put("现房", xianFangMap);


        if (CollectionUtils.isNotEmpty(houseNature2List)) {
            Map itemMap = Maps.newHashMap();
            for (House house : houseNature2List) {
                gwjPrice = house.getGwjPrice();
                if (gwjPrice.compareTo(BigDecimal.ZERO) > 0) {
                    if (qiFangMap.get(gwjPrice.toString()) == null) {
                        gwjNowPrice = BigDecimalUtils.getBigAndBigMul(house.getGwjPrice(), contract.getParameter().getGwjHouseNowBl());
                        gwjArea = house.getBuildArea();
                        gwjMoney = BigDecimalUtils.getBigAndBigMul(gwjNowPrice, gwjArea).setScale(2, BigDecimal.ROUND_HALF_UP).negate();
                    } else {
                        itemMap = qiFangMap.get(gwjPrice.toString());
                        gwjNowPrice = BigDecimalUtils.getBigAndBigMul(house.getGwjPrice(), contract.getParameter().getGwjHouseNowBl());
                        if (itemMap != null && itemMap.get("gwjArea") != null) {
                            gwjArea = BigDecimalUtils.getSum(house.getBuildArea(), BigDecimalUtils.stringToBigDecimal(itemMap.get("gwjArea").toString()));
                        }
                        gwjMoney = BigDecimalUtils.getBigAndBigMul(gwjNowPrice, gwjArea).setScale(2, BigDecimal.ROUND_HALF_UP).negate();
                        itemMap = Maps.newHashMap();
                    }
                }
                itemMap.put("gwjPrice", gwjPrice);
                itemMap.put("gwjNowPrice", gwjNowPrice);
                itemMap.put("gwjArea", gwjArea);
                itemMap.put("gwjMoney", gwjMoney);
                qiFangMap.put(gwjPrice.toString(), itemMap);
            }
        }

        map.put("期房", qiFangMap);
        return map;
    }


}
